//
//  StatusDAL.swift
//  新浪微博
//
//  Created by waterfoxjie on 15/9/3.
//  Copyright © 2015年 zj. All rights reserved.
//

import Foundation

// 开发中以60s为测试时间
private let dbCacheTime = NSTimeInterval(60) // 24 * 3600  1天

class StatusDAL {
    
    // MARK: - 清除数据库缓存数据
    /// 删除数据，本身不会让数据库变小，数据库会保留空间，出于性能考虑，数据缓存时间不适合太长
    /// 不要将太太大的数据保存在数据库中
    class func clearDatabaseCache() {
    
        // 1、确定删除缓存的日期
        let date = NSDate(timeIntervalSinceNow: -dbCacheTime)
        
        // 转换日期格式
        let df = NSDateFormatter()
        
        // 地区
        df.locale = NSLocale(localeIdentifier: "en")
        
        // 格式
        df.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        let dateString = df.stringFromDate(date)
        
        // 2、执行清除缓存的代码
        /// 技巧 ：删除时，先用select确定满足条件的记录是否能被查到，直接delete会看不到数据，容易误删数据
        let sql = "DELETE FROM T_Status WHERE createTime < '\(dateString)'"
        
        print(dateString)
        
        SQLiteManager.sharedManager.queue.inDatabase { db in
            
            db.executeUpdate(sql)
            
            print("删除成功")
        }
        
    }
    

    // MARK: - 数据访问层加载数据
    // 从数据库&网络加载
    class func loadStatus(since_id : Int , max_id : Int , finished : (array : [[String : AnyObject]]? , error : NSError?) -> ()) {
    
        // 1、检查本地是否有缓存数据
        loadCacheData(since_id, max_id: max_id) { (array) -> () in
            
            // 判断，是否有缓存数据
            if (array?.count ?? 0) > 0 {
            
                // 2、如果有缓存数据，回调
                finished(array: array, error: nil)
                
                return
                
            }
            
            // 3、没有缓存，加载网络数据
            NetworkTools.shareNetworkTools.loadStatus(since_id, max_id: max_id, finished: { (result, error) -> () in
                
                // 获取到数组，判断能否获得数组
                if let array = result?["statuses"] as? [[String : AnyObject]] {
                
                    // 4、加载完成之后，将数据保存至“数据库”
                    saveStatus(array)
                    
                    // 5、完成回调
                    finished(array: array, error: nil)
                    
                } else {
                
                    finished(array: nil, error: error)
                }
            
            })
            
        }
        
    }
    
    // MARK: - 检查本地是否有缓存
    // 1、确定参数 ：上拉、下拉刷新，回调的参数
    class func loadCacheData(since_id : Int , max_id : Int , finished : (array : [[String : AnyObject]]?) -> ()) {
        
        // 判断用户是否登录
        assert(UserAccount.userLogin, "必须登录之后才能调用")
        
        // 用户id
        let userID = UserAccount.loadAccount()!.uid!
    
        // 2、确定SQl
        var sql = "SELECT statusID , status , userID FROM T_Status \n" +
        "WHERE userID = \(userID) \n"
        
        // 根据参数，调整查询条件
        if since_id > 0 {
        
            // 下拉刷新
            sql += "AND statusID > \(since_id) \n"
            
        } else if max_id > 0 {
        
            // 上拉刷新
            sql += "AND statusID < \(max_id) \n"
            
        }
       
        sql += "ORDER BY statusID DESC LIMIT 20;"
        
        // MARK: - 测试
        print(sql)
        
        // 3、执行SQL
        SQLiteManager.sharedManager.queue.inDatabase { (db) -> Void in
            
            // 没有数据则直接返回
            guard let rs = db.executeQuery(sql) else {
                
                // 空数据回调
                finished(array: nil)
            
                return
            }
            
            // 生成查询结果 -- 返回一个[[String : AnyObject]]字典数组
            var array = [[String : AnyObject]]()
            
            while rs.next() {
            
                let jsonString = rs.stringForColumn("status")
                
                // 进行JSON反序列化
                let dict = try! NSJSONSerialization.JSONObjectWithData(jsonString.dataUsingEncoding(NSUTF8StringEncoding)!, options: NSJSONReadingOptions(rawValue: 0))
                
                // 将字典插入数组中
                array.append(dict as! [String : AnyObject])
                
            }
            
            // 通过回调返回数据
            finished(array: array)
            
        }
        
        
    }
    
    
    
    // MARK: - 数据保存到数据库
    // 1、确定参数 ：从网络上获取到的字典数组
    class func saveStatus(array : [[String : AnyObject]]) {
        
        // 判断用户是否登录(断言)
        assert(UserAccount.userLogin, "必须登录之后才能调用")
    
        // 2、确定SQL(预编译SQL)
        /// INSERT OR REPLACE INTO 这是SQLite特有的语法，写这个的时候需要注意 ：
        /// （1）字段中一定要有主键 （2）主键一定不能是自动增长的，如果是自动增长的，INSERT的时候，无法确定主键
        let sql = "INSERT OR REPLACE INTO T_Status (statusID , status , userID) VALUES (? , ? , ?);"
        
        // 第三个参数 ：用户ID
        let userID = UserAccount.loadAccount()!.uid!
        
        // 3、利用数据库工具，遍历数组，顺序插入数据
        SQLiteManager.sharedManager.queue.inTransaction { (db, roolback) -> Void in
            
            // 遍历数组
            for dict in array {
            
                // 第一个参数 ：微博代号
                let statusID = dict["id"] as! Int
                
                // 第二个参数 ：字典对应的JSON字符串，对其进行系列化操作，返回一个NSData数据
                // PrettyPrinted 表示漂亮显示，也可以直接写(rawValue: 0)
                let json = try! NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions(rawValue: 0))
                
                let jsonString = NSString(data: json, encoding: NSUTF8StringEncoding)!
                
                // 4、插入数据
                if !db.executeUpdate(sql, statusID , jsonString , userID) {
                
                    // 没有插入成功
                    roolback.memory = true
                    
                    break
                }
                
            }
            
            // 输出
            print("保存了\(array.count)条数据...")
            
        }
        
    }
    
    
    
    
    
    
}